package com.gitee.wsl.compose.mvi

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.gitee.wsl.mvi.Action
import com.gitee.wsl.mvi.BaseViewModel
import com.gitee.wsl.mvi.Effect
import com.gitee.wsl.mvi.State
import com.gitee.wsl.result.EntryResult
import com.gitee.wsl.result.tran.filterSuccess
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn

abstract class BaseStateViewModel<S : State> : ViewModel() {

    abstract fun initialState(): S

    private val _viewState: MutableState<S> by lazy { mutableStateOf(initialState()) }

    val viewState: androidx.compose.runtime.State<S> = _viewState

    /**
     * Share the flow in [viewModelScope],
     * start when the first subscriber arrives,
     * and stop when the last subscriber leaves.
     */
    protected fun <T> Flow<T>.shareWhileSubscribed(): SharedFlow<T> =
        shareIn(viewModelScope, SharingStarted.WhileSubscribed())

    protected fun <T> Flow<T>.stateWithInitialNullWhileSubscribed(): StateFlow<T?> =
        stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
}


/**在view中用于订阅*/
val <A : Action, S : State, E : Effect> BaseViewModel<A, S, E>.resultState: StateFlow<EntryResult<S, Exception>>
    get() = _state.asStateFlow()

val <A : Action, S : State, E : Effect> BaseViewModel<A , S , E >.state: StateFlow<S>
    get() = this.resultStateFlow.filterSuccess().stateIn(viewModelScope, SharingStarted.Lazily,initialState())

